<script setup>
import IconAi from '@/components/icons/IconAi.vue'
import IconPaid from '@/components/icons/IconPaid.vue'
import IconRefund from '@/components/icons/IconRefund.vue'
import IconReBook from '@/components/icons/IconReBook.vue'
import { listOrders } from '@/api/OrderService.js'
import { onMounted, ref } from 'vue'
import Toast from 'primevue/toast'
import { useToast } from 'primevue/usetoast'
import { FilterMatchMode } from '@primevue/core/api'
import { listUsers } from '@/api/UserService.js'
import { listTrains } from '@/api/TrainService.js'
import { listCarriages } from '@/api/CarriageService.js'
import { listSeats } from '@/api/SeatService.js'

const toast = useToast()

// 订单列表
const orders = ref([])
// 控制退款费用和退款时间是否显示
const isRefundFee = ref(false)
const isRefundTime = ref(false)
// 表格渲染数据懒加载
const loading = ref(false)
// 用户信息
const users = ref([])
// 用户对话框是否展示
const userVisible = ref(false)
// 车次列表
const trains = ref([])
// 车次对话框
const trainVisible = ref(false)
// 车厢列表
const carriages = ref([])
// 车厢对话框
const carriageVisible = ref(false)

// 座位列表
const seats = ref([])
// 座位对话框
const seatVisible = ref(false)
// AI客服对话框
const aiVisible = ref(false)
// 控制对话框显示位置
const position = ref('center')

/**
 * 搜索功能
 */
const filters = ref({
  global: { value: null, matchMode: FilterMatchMode.CONTAINS },
})

/**
 * 列出所有订单信息
 */
const initOrderInfo = () => {
  // 1.开启懒加载
  loading.value = true

  // 2.获取订单列表
  listOrders()
    .then((res) => {
      if (res.code === 200) {
        orders.value = res.data
        orders.value.forEach((item) => {
          // 控制退票费用和退票时间是否显示
          if (item.refundFee !== null) {
            isRefundFee.value = true
          }else {
            isRefundFee.value = false
          }
          if (item.refundTime !== null) {
            isRefundTime.value = true
          }else {
            isRefundTime.value = false
          }
        })
      }

      // 3.关闭懒加载
      loading.value = false
    })
    .catch((error) => {
      console.error('请求失败:', error)
    })
}

/**
 * 加上货币前缀
 * @param value 票价
 */
const formatCurrency = (value) => {
  return value.toLocaleString('zh-CN', { style: 'currency', currency: 'CNY' })
}

/**
 * 初始化
 */
onMounted(() => {
  initOrderInfo()
})

/**
 * 查看用户信息
 */
const showUserInfo = () => {
  // 1.打开对话
  userVisible.value = true

  loading.value = true
  // 2.获取用户列表
  listUsers().then((res) => {
    if (res.code === 200) {
      users.value = res.data
    }
  })
  loading.value = false
}

/**
 * 查看车次信息
 */
const showTrainInfo = () => {
  // 1.打开对话
  trainVisible.value = true

  loading.value = true
  // 2.获取车次列表
  listTrains().then((res) => {
    if (res.code === 200) {
      trains.value = res.data
    }
  })
  loading.value = false
}

/**
 * 查看车厢信息
 */
const showCarriageInfo = () => {
  // 1.打开对话
  carriageVisible.value = true
  loading.value = true
  // 2.获取车厢列表
  listCarriages().then((res) => {
    if (res.code === 200) {
      carriages.value = res.data
    }
  })
  loading.value = false
}

/**
 * 查看座位信息
 */
const showSeatInfo = () => {
  // 1.打开对话
  seatVisible.value = true
  loading.value = true
  // 2.获取车厢列表
  listSeats().then((res) => {
    if (res.code === 200) {
      seats.value = res.data
    }
  })
  loading.value = false
}

/**
 * 购票
 */
const buyTicket = () => {
  toast.add({
    severity: 'warn',
    summary: '警告',
    detail: '请点击AI客服按钮按照提示完成此功能',
    life: 3000,
  })
}

/**
 * AI客服
 */
const aiCustomerService = (pos) => {
  position.value = pos
  aiVisible.value = true
}

/**
 * 改签
 */
const reBook = () => {
  toast.add({
    severity: 'warn',
    summary: '警告',
    detail: '请点击AI客服按钮按照提示完成此功能',
    life: 3000,
  })
}

/**
 * 退票
 */
const refundTicket = () => {
  toast.add({
    severity: 'warn',
    summary: '警告',
    detail: '请点击AI客服按钮按照提示完成此功能',
    life: 3000,
  })
}

// ai时间线测试
// events数据结构如下: 对话历史
const chatEventsHistory = ref([
  {
    chatTitle: '👏🎉欢迎来到【大源数】智能铁路(🚄🚂)站！请问有什么可以帮您的?',
    chatDateTime: new Date().toLocaleDateString() + ' ' + new Date().toLocaleTimeString(),
    chatContent: '请说出您的需求...',
    color: '#9C27B0',
    icon: 'pi pi-microchip-ai',
  },
])

// 用户聊天框中输入的数据
const userInputMessageValue = ref('')
// 计数器
let count = 2
// 事件源
let eventSource

/**
 * 发送消息
 */
const sendMessage = () => {
  if (eventSource) {
    eventSource.close()
  }
  // 对话历史记录中追加数据
  chatEventsHistory.value.push({
    chatTitle: `${truncateString(userInputMessageValue.value)}`,
    chatDateTime: new Date().toLocaleDateString() + ' ' + new Date().toLocaleTimeString(),
    chatContent: `✨你说的😊: ${userInputMessageValue.value}`,
    color: '#94f350',
    icon: 'pi pi-users',
  })

  chatEventsHistory.value.push({
    chatTitle: '🤖等待系统回复中...',
    chatDateTime: new Date().toLocaleDateString() + ' ' + new Date().toLocaleTimeString(),
    chatContent: '💻等待中...',
    color: '#9C27B0',
    icon: 'pi pi-microchip-ai',
  })

  // sse: 服务端推送 Server-Sent Events
  eventSource = new EventSource(
    `http://localhost:8099/ai/generateStreamAsString?message=${userInputMessageValue.value}`,
  )
  userInputMessageValue.value = ''
  eventSource.onmessage = (event) => {
    if (event.data === '[complete]') {
      count = count + 2
      eventSource.close()
      // 每次对话完后刷新列表
      initOrderInfo()
      return
    }
    chatEventsHistory.value[count].chatContent += event.data
  }
  eventSource.onopen = (event) => {
    chatEventsHistory.value[count].chatContent = ''
  }
}

/**
 * 截取字符串前20个字（中/英文均计1字）
 * @param {string} str - 原始字符串
 * @param {boolean} ellipsis - 是否添加省略号（默认：true）
 * @returns {string} 处理后的字符串
 */
function truncateString(str, ellipsis = true) {
  if (!str) return '' // 处理空值
  const maxLength = 20
  const truncated = str.slice(0, maxLength)

  // 检查是否需要截断（处理全角空格等特殊字符）
  if (str.length > maxLength && ellipsis) {
    return truncated + '...'
  }
  return truncated
}
</script>

<template>
  <main>
    <div class="card">
      <Toolbar style="margin-bottom: 6px">
        <template #start>
          <Toast />
          <Button
            label="查看用户"
            icon="pi pi-info"
            severity="help"
            style="margin-right: 2rem"
            @click="showUserInfo"
          />
          <Button
            label="查看车次"
            icon="pi pi-info-circle"
            severity="info"
            style="margin-right: 2rem"
            @click="showTrainInfo"
          />
          <Button
            label="查看车厢"
            icon="pi pi-info-circle"
            severity="contrast"
            style="margin-right: 2rem"
            @click="showCarriageInfo"
          />
          <Button
            label="查看座位"
            icon="pi pi-info-circle"
            severity="secondary"
            style="margin-right: 2rem"
            @click="showSeatInfo"
          />
        </template>

        <template #end>
          <Button label="购票" icon="pi pi-plus" style="margin-right: 2rem" @click="buyTicket" />
          <Button style="margin-right: 1rem" severity="help" @click="aiCustomerService('topright')">
            <IconAi />
            客服
          </Button>
        </template>
      </Toolbar>
      <DataTable
        dataKey="id"
        ref="dt"
        :value="orders"
        :paginator="true"
        :row-hover="true"
        :rows="10"
        :filters="filters"
        :loading="loading"
        paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
        :rowsPerPageOptions="[5, 10, 25]"
        currentPageReportTemplate="显示 {first} 到 {last}条记录， 共计 {totalRecords} 个订单"
      >
        <template #header>
          <div class="header-container">
            <h2 class="title" style="margin: 0">订单列表</h2>
            <div class="search-container">
              <IconField>
                <InputIcon>
                  <i class="pi pi-search" />
                </InputIcon>
                <InputText v-model.trim="filters['global'].value" placeholder="键入关键字搜索..." />
              </IconField>
            </div>
          </div>
        </template>
        <Column field="orderId" header="订单" style="min-width: 2rem"></Column>
        <Column field="passengerName" header="乘客" style="min-width: 2rem"></Column>
        <Column field="trainNumber" header="车次" style="min-width: 2rem"></Column>
        <Column field="departureTime" header="出发时间" style="min-width: 2rem"></Column>
        <Column field="departureStation" header="出发站" style="min-width: 2rem"></Column>
        <Column field="arrivalStation" header="到达站" style="min-width: 2rem"></Column>
        <Column field="seatInfo" header="车厢+座位" style="min-width: 2rem"></Column>
        <Column field="orderStatus" header="订单状态" style="min-width: 2rem">
          <template #body="slotProps">
            <span v-if="slotProps.data.orderStatus === '已付款'">
              <IconPaid />
            </span>
            <span v-else-if="slotProps.data.orderStatus === '已退票'">
              <IconRefund />
            </span>
            <span v-else-if="slotProps.data.orderStatus === '已改签'">
              <IconReBook />
            </span>
            <span v-else>
              {{ slotProps.data.orderStatus }}
            </span>
          </template>
        </Column>
        <Column field="amount" header="票价" style="min-width: 2rem">
          <template #body="slotProps">
            {{ formatCurrency(slotProps.data.amount) }}
          </template>
        </Column>
        <Column
          v-if="isRefundTime"
          field="refundTime"
          header="退款时间"
          style="min-width: 2rem"
        ></Column>
        <Column
          v-if="isRefundFee"
          field="refundFee"
          header="退款费用"
          style="min-width: 2rem"
        >
        </Column>
        <Column :exportable="false" style="min-width: 7rem">
          <template #body="slotProps">
            <Button
              icon="pi pi-user-edit"
              label="改签"
              outlined
              rounded
              style="margin-right: 0.4rem"
              @click="reBook(slotProps.data)"
            />
            <Button
              icon="pi pi-backward"
              label="退票"
              outlined
              rounded
              severity="danger"
              @click="refundTicket(slotProps.data)"
            />
          </template>
        </Column>
      </DataTable>
      <!--控制用户信息的对话框-->
      <div class="card flex justify-center">
        <Dialog v-model:visible="userVisible" modal header="用户信息" :style="{ width: '55rem' }">
          <div>
            <DataTable :value="users" dataKey="id" tableStyle="min-width: 50rem" :row-hover="true">
              <Column field="id" header="编号"></Column>
              <Column field="username" header="用户名"></Column>
              <Column field="realName" header="真实姓名"></Column>
              <Column field="idCard" header="身份证"></Column>
              <Column field="phone" header="手机号"></Column>
              <Column field="email" header="邮箱"></Column>
            </DataTable>
          </div>
        </Dialog>
      </div>
      <!--车次对话框-->
      <div class="card flex justify-center">
        <Dialog v-model:visible="trainVisible" modal header="车次信息" :style="{ width: '55rem' }">
          <div>
            <DataTable :value="trains" dataKey="id" tableStyle="min-width: 50rem" :row-hover="true">
              <Column field="id" header="编号"></Column>
              <Column field="trainNumber" header="车次"></Column>
              <Column field="departureStation" header="出发站"></Column>
              <Column field="arrivalStation" header="到达站"></Column>
              <Column field="departureTime" header="出发时间"></Column>
              <Column field="arrivalTime" header="到达时间"></Column>
              <Column field="price" header="票价"></Column>
            </DataTable>
          </div>
        </Dialog>
      </div>
      <!--车厢对话框-->
      <div class="card flex justify-center">
        <Dialog
          v-model:visible="carriageVisible"
          modal
          header="车厢信息"
          :style="{ width: '55rem' }"
        >
          <div>
            <DataTable
              :value="carriages"
              dataKey="id"
              tableStyle="min-width: 50rem"
              :row-hover="true"
            >
              <Column field="trainNumber" header="车次"></Column>
              <Column field="carriageNumber" header="车厢号"></Column>
              <Column field="carriageTypeName" header="车厢类型"></Column>
              <Column field="totalSeats" header="车厢总座位数"></Column>
            </DataTable>
          </div>
        </Dialog>
      </div>
      <!--座位对话框-->
      <div class="card flex justify-center">
        <Dialog
          v-model:visible="seatVisible"
          modal
          header="座位信息"
          :style="{ width: '55rem' }"
          :breakpoints="{ '1199px': '75vw', '575px': '90vw' }"
        >
          <div>
            <DataTable :value="seats" dataKey="id" tableStyle="min-width: 50rem" :row-hover="true">
              <Column field="trainNumber" header="车次"></Column>
              <Column field="carriageNumber" header="车厢号"></Column>
              <Column field="carriageTypeName" header="车厢类型"></Column>
              <Column field="totalSeats" header="车厢总座位数"></Column>
              <Column field="seatNumber" header="座位"></Column>
              <Column field="seatTypeName" header="座位类型"></Column>
              <Column field="seatStatusName" header="座位状态"></Column>
            </DataTable>
          </div>
        </Dialog>
      </div>
      <!--*****重点：AI客服实现自动购票、改签、退票功能*****start-->
      <div>
        <Dialog
          v-model:visible="aiVisible"
          :position="position"
          maximizable
          modal
          :breakpoints="{ '1199px': '75vw', '575px': '90vw' }"
          header="AI智能客服"
          :style="{ width: '45rem' }"
        >
          <!--*****这是AI客服对答时间线*****start-->
          <Timeline :value="chatEventsHistory" align="left">
            <template #marker="slotProps">
              <span :style="{ color: slotProps.item.color }">
                <i :class="slotProps.item.icon"></i>
              </span>
            </template>
            <template #content="slotProps">
              <Card>
                <template #title>
                  {{ slotProps.item.chatTitle }}
                </template>
                <template #subtitle>
                  <span style="color: #e38383">
                    {{ slotProps.item.chatDateTime }}
                  </span>
                </template>
                <template #content>
                  <p>
                    {{ slotProps.item.chatContent }}
                  </p>
                </template>
              </Card>
            </template>
          </Timeline>
          <!--*****这是AI客服对答时间线*****end-->
          <Divider type="dashed" style="margin-left: 28px; font-weight: bold" />
          <!--*****AI对话框*****start-->
          <div style="margin-left: 28px">
            <InputText
              type="text"
              placeholder="您可以输入购票、改签、退票等信息，按回车键即可发送"
              v-model="userInputMessageValue"
              @keyup.enter="sendMessage()"
              style="
                width: 86%;
                height: 55px;
                border-bottom-right-radius: 0;
                border-top-right-radius: 0;
              "
            />
            <Button
              label="发送"
              severity="success"
              style="height: 55px; border-top-left-radius: 0; border-bottom-left-radius: 0"
              @click="sendMessage()"
            />
          </div>
          <!--*****AI对话框*****end-->
        </Dialog>
      </div>
      <!--*****重点：AI客服实现自动购票、改签、退票功能*****end-->
    </div>
  </main>
</template>
<style scoped>
.card {
  margin: 1.5rem;
}

.header-container {
  display: flex;
  /* 垂直居中 */
  align-items: center;
  /* 标题与搜索框之间的间距 */
  gap: 16px;
}

.title {
  /* 让标题靠左，搜索框靠右（可选） */
  margin-right: auto;
}

.search-container {
  /* 可选：调整搜索框的宽度或样式 */
  /* 关键：右对齐 */
  margin-left: auto;
  /* 可选：清除默认右外边距 */
  margin-right: 0;
}

@media (max-width: 768px) {
  .header-container {
    /* 移动端垂直排列 */
    flex-direction: column;
    align-items: flex-start;
  }

  .search-container {
    /* 移除右对齐 */
    margin-left: 0;
    /* 增加垂直间距 */
    margin-top: 8px;
  }
}

/* 时间线左边部分不显示 */
:deep(.p-timeline-event-opposite) {
  display: none;
}

/* 去掉时间线卡片的内边距 */
:deep(.p-card-body) {
  padding: 0;
}

/* 时间线卡片标题字体大小修改 */
:deep(.p-card-title) {
  font-size: 1rem;
}
</style>
